package cn.imvc.app.models;



import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import cn.imvc.app.commons.SystemConfig;
import cn.imvc.app.domains.Constants;
import cn.imvc.app.domains.FundFlowType;
import cn.imvc.app.entities.FundFlow;
import cn.imvc.app.entities.Member;
import cn.imvc.app.repositories.FundFlowRepository;
import cn.imvc.data.domain.ViewRequest;
import cn.imvc.util.AES;

@Service
public class FundFlowModelImpl implements FundFlowModel{
	
	@Autowired
	private FundFlowRepository fundFlowRepository;
	@Autowired
	SystemConfig systemConfig;
	
	
	public FundFlow get(int id){
		return fundFlowRepository.findOne(id);
	}
	
	
	@SuppressWarnings("unchecked")
	public Page<FundFlow> find(ViewRequest viewRequest) {
		return (Page<FundFlow>) fundFlowRepository.findAll();
	}

	public FundFlow save(FundFlow fundFlow) {
		
		FundFlow fundFlow2 = fundFlowRepository.saveAndFlush(fundFlow);
		
		
		return fundFlow2;
	}
	public FundFlow update(FundFlow newFundFlow) {
		FundFlow loadFundFlow=get(newFundFlow.getId());
		BeanUtils.copyProperties(newFundFlow, loadFundFlow, new String[]{"id"});
		
		return fundFlowRepository.saveAndFlush(loadFundFlow);
	}
	public void delete(int id) {
		fundFlowRepository.delete(id);
		
	}
	public void deleteBatch(int[] ids) {

		for (int id : ids) {
			delete(id);
		}
		
	}
	public void addFundFlow(Member member,Integer money,String code,Byte type,Member fromMember){
		if (money==0){
			return;
		}
		FundFlow fundFlow=new FundFlow();
		fundFlow.setAccount(member.getAccount());
		fundFlow.setMember(member);
		fundFlow.setCode(code);
		fundFlow.setType(type);
		Calendar cal=Calendar.getInstance();
		cal.get(Calendar.YEAR);
		fundFlow.setYear(cal.get(Calendar.YEAR));
		fundFlow.setMonth(cal.get(Calendar.MONTH)+1);
		fundFlow.setDay(cal.get(Calendar.DATE));
		fundFlow.setSigned(money>=0?"+":"-");
		fundFlow.setMoney(Math.abs(money));
		fundFlow.setAmount(money);
		fundFlow.setCreatedAt(new Date());
		fundFlow.setUpdatedAt(new Date());
		fundFlow.setVerify(AES.encrypt(money+"",systemConfig.getAESPassword()));
		fundFlow.setFromMember(fromMember);
		save(fundFlow);
	}
	
	public Page<FundFlow> findMoneyPage(Member member, Integer page, Byte type) {
		List<Byte> types = getFundFlowTypes(type);
		PageRequest pageRequest = new PageRequest(page, Constants.MONEY_PAGE_SIZE, null);
		Page<FundFlow> list = fundFlowRepository.findByMemberAndTypeInOrderByCreatedAtDesc(member, types, pageRequest);
		return list;
	}
	
	public Page<FundFlow> findMoneyPage(Member member, Pageable page, Byte type) {
		List<Byte> types = getFundFlowTypes(type);
		return fundFlowRepository.findByMemberAndTypeInOrderByCreatedAtDesc(member, types, page);
	}
	
	private List<Byte> getFundFlowTypes(Byte type){
		List<Byte> types = new ArrayList<Byte>();
		if(type == (byte)0){
			types.add(FundFlowType.Recharge.getValue());
			types.add(FundFlowType.Withdrawals.getValue());
			types.add(FundFlowType.TeamAward.getValue());
			types.add(FundFlowType.Buy.getValue());
			types.add(FundFlowType.Refund.getValue());
		} else if(type == (byte)1){
			types.add(FundFlowType.PointsUp.getValue());
			types.add(FundFlowType.PointsDown.getValue());
			types.add(FundFlowType.PointsRecommend.getValue());
			types.add(FundFlowType.PointsCommission.getValue());
		} else if(type == (byte)2){
			types.add(FundFlowType.Buy.getValue());
			types.add(FundFlowType.Refund.getValue());
			types.add(FundFlowType.PointsDown.getValue());
		} else {
			types.add(type);
			// 购买商品显示扣款和退款，提现记录显示成功和失败退款
			if(type == FundFlowType.Buy.getValue()){
				types.add(FundFlowType.Refund.getValue());
			} else if(type == FundFlowType.Refund.getValue()){
				types.add(FundFlowType.Buy.getValue());
			} else if(type == FundFlowType.Withdrawals.getValue()){
				types.add(FundFlowType.WithdrawalsFailed.getValue());
			} else if(type == FundFlowType.WithdrawalsFailed.getValue()){
				types.add(FundFlowType.Withdrawals.getValue());
			} else if(type == FundFlowType.PointsToMoney_Points.getValue()){
				types.add(FundFlowType.PointsToMoney_Money.getValue());
			}
		}
		return types;
	}

}
